﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace WSAP
{
    /***
     * 等跨等高框架结构算例
     * HorizontalLoadLinearAnalyzeExample：静力加载不考虑二阶效应
     * HorizontalLoadGeneralAnalyzeExample：静力加载考虑二阶效应
     * EigenExample：模态分析
     * 使用DoEigen进行模态分析
    ****/

    /// <summary>
    /// 框架结构基本实例
    /// </summary>
    public static class WSAPFrame
    {
        /// <summary>
        /// 框架结构施加水平力
        /// </summary>
        /// <param name="cDimension"></param>
        /// <param name="bWidth"></param>
        /// <param name="bHeight"></param>
        /// <param name="spanLength"></param>
        /// <param name="storeyHeight"></param>
        /// <param name="spanNum"></param>
        /// <param name="storeyNum"></param>
        /// <returns></returns>
        public static bool HorizontalLoadLinearAnalyzeExample(this WModelNet model, double vLoad, double hLoad, bool isStatic)
        {
            //创建有限元模型
            var domain = model.GetDomain();
            //增加荷载
            if (!model.SetNodeLoad(domain, vLoad, hLoad)) return domain.ShowWarningError();
            //求解
            if (!domain.LinearAnalyze()) return domain.ShowWarningError();
            //绘图
            return model.Show(StructureChartType.GeneralStatic, isStatic);
        }

        /// <summary>
        /// 框架结构施加水平力
        /// </summary>
        /// <param name="cDimension"></param>
        /// <param name="bWidth"></param>
        /// <param name="bHeight"></param>
        /// <param name="spanLength"></param>
        /// <param name="storeyHeight"></param>
        /// <param name="spanNum"></param>
        /// <param name="storeyNum"></param>
        /// <returns></returns>
        public static bool HorizontalLoadGeneralAnalyzeExample(WModelNet model, double vLoad, double hLoad, bool isStatic)
        {
            //创建有限元模型
            var domain = model.GetDomain();
            //增加荷载
            if (!model.SetNodeLoad(domain, vLoad, hLoad)) return domain.ShowWarningError();
            //求解
            if (!domain.GeneralAnalyze(1)) return domain.ShowWarningError();
            //绘图
            return model.Show(StructureChartType.GeneralStatic, isStatic);
        }

        /// <summary>
        /// 模态分析
        /// </summary>
        /// <param name="cDimension"></param>
        /// <param name="bWidth"></param>
        /// <param name="bHeight"></param>
        /// <param name="spanLength"></param>
        /// <param name="storeyHeight"></param>
        /// <param name="spanNum"></param>
        /// <param name="storeyNum"></param>
        /// <param name="vLoad"></param>
        /// <param name="hLoad"></param>
        /// <returns></returns>
        public static bool EigenExample(this WModelNet model, double nodeMass, int eigenNumber, bool isStatic)
        {
            //增加质量
            if (!model.SetNodeMass(nodeMass)) return false;
            //创建有限元模型
            var domain = model.GetDomain();
            //模态分析
            var periodList = domain.Eigen(eigenNumber);
            //显示结构模态信息
            WSAPHelper.ShowPeriodInfo(periodList);
            //绘图
            return model.Show(StructureChartType.Eigen, isStatic);
        }

        /// <summary>
        /// 创建模型
        /// </summary>
        /// <param name="cWidth"></param>
        /// <param name="cHeight"></param>
        /// <param name="bWidth"></param>
        /// <param name="bHeight"></param>
        /// <param name="spanLength"></param>
        /// <param name="storeyHeight"></param>
        /// <param name="spanNum"></param>
        /// <param name="storeyNum"></param>
        /// <returns></returns>
        public static WModelNet GetWModelNet(double cDimension, double bWidth, double bHeight, 
            double spanLength, double storeyHeight,
            int spanNum, int storeyNum,
            double beamRigidEndLength)
        {
            //初始化模型参数
            var model = new WModelNet();
            //遍历结构高度
            for (int h = 0; h <= storeyNum; h++)
            {
                for (int y = 0; y <= spanNum; y++)
                {
                    for (int x = 0; x <= spanNum; x++)
                    {
                        //计算坐标
                        var nodeCI = new XYZPairNet(x * spanLength, y * spanLength, (h - 1) * storeyHeight);
                        var nodeJ = new XYZPairNet(x * spanLength, y * spanLength, h * storeyHeight);
                        //增加柱
                        model.AddRectangularConcreteFrame(nodeCI, nodeJ, cDimension, cDimension);
                        //添加横向梁
                        if (x != 0)
                        {
                            var nodeBI = new XYZPairNet((x - 1) * spanLength, y * spanLength, h * storeyHeight);
                            model.AddRectangularConcreteFrame(nodeBI, nodeJ, bWidth, bHeight);
                        }
                        //纵向梁
                        if (y != 0)
                        {
                            var nodeBI = new XYZPairNet(x * spanLength, (y - 1) * spanLength, h * storeyHeight);
                            model.AddRectangularConcreteFrame(nodeBI, nodeJ, bWidth, bHeight);
                        }
                    }
                }
            }
            //约束
            model.FixZ(0);
            return model;
        }

        /// <summary>
        /// 设定节点力
        /// </summary>
        /// <param name="model"></param>
        /// <param name="vLoad"></param>
        /// <param name="hLoad"></param>
        private static bool SetNodeLoad(this WModelNet model, WDomainNet domain, double vLoad, double hLoad)
        {
            //遍历节点给X轴上的单元施加水平力
            foreach (var node in model.GetNodes())
            {
                if (node.GetZ() != 0)
                {
                    //增加竖向力
                    if (!domain.AddNodeLoad(node.GetTag(), 3, vLoad))
                        return false;
                    //增加水平力
                    if (!domain.AddNodeLoad(node.GetTag(), 1, hLoad))
                        return false;
                }
            }
            return true;
        }

        /// <summary>
        /// 设定节点质量
        /// </summary>
        /// <param name="model"></param>
        /// <param name="nodeMass"></param>
        private static bool SetNodeMass(this WModelNet model, double nodeMass)
        {
            //增加质量
            foreach (var node in model.GetNodes())
            {
                if (node.GetZ() != 0)
                {
                    //增加竖向力
                    if (!node.SetMass(nodeMass, 0))
                        return false;
                }
            }
            return true;
        }

        /// <summary>
        /// 设定节点力
        /// </summary>
        /// <param name="model"></param>
        /// <param name="vLoad"></param>
        /// <param name="hLoad"></param>
        private static bool Show(this WModelNet model, StructureChartType chartType, bool isStatic)
        {
            //动态
            if(!isStatic)
            {
                model.ToDynamicGraphics(new StructrueChartParam(chartType));
                return true;
            }
            else if (chartType == StructureChartType.Eigen)
            {
                model.ToGraphics(new StructrueChartParam(chartType));
                return true;
            }
            else if (chartType == StructureChartType.GeneralStatic)
            {
                //绘图
                model.ToGraphics(new StructrueChartParam
                {
                    DOF = 1,
                    isNodeMaxResponseShow = true,
                    ChartType = StructureChartType.GeneralStatic,
                });
                return true;
            }
            return false;
        }
    }
}
